package com.zenithmind.document.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.document.mapper.DocumentFavoriteMapper;
import com.zenithmind.document.pojo.domain.DocumentFavorite;
import com.zenithmind.document.pojo.query.DocumentFavoriteQueryDTO;
import com.zenithmind.document.pojo.vo.DocumentFavoriteVO;
import com.zenithmind.document.service.DocumentFavoriteService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 文档收藏服务实现类
 * 遵循单一职责原则：专注于文档收藏功能
 * 遵循依赖倒置原则：依赖抽象接口而不是具体实现
 * 遵循封装原则：通过方法控制收藏状态和权限
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DocumentFavoriteServiceImpl extends ServiceImpl<DocumentFavoriteMapper, DocumentFavorite> implements DocumentFavoriteService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean favoriteDocument(String documentId, String userId, String folderName) {
        log.info("收藏文档: documentId={}, userId={}, folderName={}", documentId, userId, folderName);
        
        // 检查是否已收藏
        if (isFavorited(documentId, userId)) {
            throw new RuntimeException("文档已收藏");
        }
        
        DocumentFavorite favorite = DocumentFavorite.create(documentId, userId, folderName);
        
        return save(favorite);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean unfavoriteDocument(String documentId, String userId) {
        log.info("取消收藏文档: documentId={}, userId={}", documentId, userId);
        
        DocumentFavorite favorite = baseMapper.selectByDocumentAndUser(documentId, userId);
        if (favorite == null) {
            return true; // 已经不存在收藏记录
        }
        
        favorite.cancel();
        
        return updateById(favorite);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer batchFavoriteDocuments(List<String> documentIds, String userId, String folderName) {
        log.info("批量收藏文档: documentIds={}, userId={}, folderName={}", documentIds, userId, folderName);
        
        int successCount = 0;
        for (String documentId : documentIds) {
            try {
                if (!isFavorited(documentId, userId)) {
                    DocumentFavorite favorite = DocumentFavorite.create(documentId, userId, folderName);
                    if (save(favorite)) {
                        successCount++;
                    }
                }
            } catch (Exception e) {
                log.warn("收藏文档失败: documentId={}, error={}", documentId, e.getMessage());
            }
        }
        
        return successCount;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer batchUnfavoriteDocuments(List<String> documentIds, String userId) {
        log.info("批量取消收藏文档: documentIds={}, userId={}", documentIds, userId);
        
        return baseMapper.batchCancelFavorites(documentIds, userId);
    }

    @Override
    public Boolean isFavorited(String documentId, String userId) {
        log.info("检查文档是否已收藏: documentId={}, userId={}", documentId, userId);
        
        return baseMapper.checkFavoriteExists(documentId, userId);
    }

    @Override
    public IPage<DocumentFavoriteVO> getFavoritePage(DocumentFavoriteQueryDTO queryDTO) {
        log.info("分页查询用户收藏");
        
        Page<DocumentFavoriteVO> page = new Page<>(queryDTO.getCurrent(), queryDTO.getSize());
        
        return baseMapper.selectFavoritePageWithDetails(page, queryDTO);
    }

    @Override
    public List<DocumentFavoriteVO> getUserFavorites(String userId, String folderName, Integer limit) {
        log.info("获取用户收藏列表: userId={}, folderName={}", userId, folderName);
        
        return baseMapper.selectUserFavorites(userId, folderName, limit);
    }

    @Override
    public List<DocumentFavoriteVO> getDocumentFavoriteUsers(String documentId, Integer limit) {
        log.info("获取文档收藏用户列表: documentId={}", documentId);
        
        return baseMapper.selectDocumentFavoriteUsers(documentId, limit);
    }

    @Override
    public List<String> getUserFavoriteFolders(String userId) {
        log.info("获取用户收藏夹列表: userId={}", userId);
        
        return baseMapper.selectUserFavoriteFolders(userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean createFavoriteFolder(String userId, String folderName, String description) {
        log.info("创建收藏夹: userId={}, folderName={}", userId, folderName);
        
        // 检查收藏夹是否已存在
        if (baseMapper.checkFolderExists(userId, folderName)) {
            throw new RuntimeException("收藏夹已存在");
        }
        
        return baseMapper.createFavoriteFolder(userId, folderName, description) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteFavoriteFolder(String userId, String folderName) {
        log.info("删除收藏夹: userId={}, folderName={}", userId, folderName);
        
        // 检查是否为默认收藏夹
        if ("默认收藏夹".equals(folderName)) {
            throw new RuntimeException("不能删除默认收藏夹");
        }
        
        // 将该收藏夹下的收藏移动到默认收藏夹
        baseMapper.moveFavoritesToDefaultFolder(userId, folderName);
        
        // 删除收藏夹
        return baseMapper.deleteFavoriteFolder(userId, folderName) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean renameFavoriteFolder(String userId, String oldFolderName, String newFolderName) {
        log.info("重命名收藏夹: userId={}, oldFolderName={}, newFolderName={}", userId, oldFolderName, newFolderName);
        
        // 检查是否为默认收藏夹
        if ("默认收藏夹".equals(oldFolderName)) {
            throw new RuntimeException("不能重命名默认收藏夹");
        }
        
        // 检查新名称是否已存在
        if (baseMapper.checkFolderExists(userId, newFolderName)) {
            throw new RuntimeException("新收藏夹名称已存在");
        }
        
        return baseMapper.renameFavoriteFolder(userId, oldFolderName, newFolderName) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean moveFavoritesToFolder(List<String> favoriteIds, String targetFolderName, String userId) {
        log.info("移动收藏到其他收藏夹: favoriteIds={}, targetFolderName={}, userId={}", favoriteIds, targetFolderName, userId);
        
        // 验证权限
        for (String favoriteId : favoriteIds) {
            DocumentFavorite favorite = getById(favoriteId);
            if (favorite == null || !userId.equals(favorite.getUserId())) {
                throw new RuntimeException("无权限操作收藏: " + favoriteId);
            }
        }
        
        return baseMapper.moveFavoritesToFolder(favoriteIds, targetFolderName, userId) > 0;
    }

    @Override
    public List<DocumentFavoriteVO> searchUserFavorites(String userId, String keyword, Integer limit) {
        log.info("搜索用户收藏: userId={}, keyword={}", userId, keyword);
        
        return baseMapper.searchUserFavorites(userId, keyword, limit);
    }

    @Override
    public Object getFavoriteStatistics(String userId) {
        log.info("获取收藏统计信息: userId={}", userId);
        
        return baseMapper.selectFavoriteStatistics(userId);
    }

    @Override
    public List<Object> getHotFavoriteDocuments(Integer limit) {
        log.info("获取热门收藏文档");
        
        return baseMapper.selectHotFavoriteDocuments(limit);
    }

    @Override
    public List<DocumentFavoriteVO> getRecentFavorites(String userId, Integer limit) {
        log.info("获取最近收藏: userId={}", userId);
        
        return baseMapper.selectRecentFavorites(userId, limit);
    }

    @Override
    public Object exportUserFavorites(String userId, String folderName) {
        log.info("导出用户收藏: userId={}, folderName={}", userId, folderName);
        
        // 实现收藏导出逻辑
        try {
            // 构建查询条件
            com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<DocumentFavorite> wrapper =
                    new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<>();
            wrapper.eq("user_id", userId).eq("status", 1);

            if (folderName != null && !folderName.trim().isEmpty()) {
                wrapper.eq("folder_name", folderName);
            }

            // 获取收藏列表
            java.util.List<DocumentFavorite> favorites = list(wrapper);

            // 构建导出数据
            java.util.Map<String, Object> exportData = new java.util.HashMap<>();
            exportData.put("exportTime", java.time.LocalDateTime.now());
            exportData.put("userId", userId);
            exportData.put("folderName", folderName);
            exportData.put("totalCount", favorites.size());
            exportData.put("favorites", favorites);

            log.info("收藏导出完成: userId={}, folderName={}, count={}", userId, folderName, favorites.size());
            return exportData;

        } catch (Exception e) {
            log.error("收藏导出失败: userId={}, folderName={}", userId, folderName, e);
            return java.util.Collections.singletonMap("error", "导出失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer importUserFavorites(String userId, Object importData) {
        log.info("导入用户收藏: userId={}", userId);
        
        // 实现收藏导入逻辑
        try {
            if (importData == null) {
                return 0;
            }

            int importedCount = 0;

            // 处理不同类型的导入数据
            if (importData instanceof java.util.Map) {
                @SuppressWarnings("unchecked")
                java.util.Map<String, Object> dataMap = (java.util.Map<String, Object>) importData;

                @SuppressWarnings("unchecked")
                java.util.List<java.util.Map<String, Object>> favoritesList =
                    (java.util.List<java.util.Map<String, Object>>) dataMap.get("favorites");

                if (favoritesList != null) {
                    for (java.util.Map<String, Object> favoriteData : favoritesList) {
                        try {
                            DocumentFavorite favorite = new DocumentFavorite();
                            favorite.setUserId(userId);
                            favorite.setDocumentId((String) favoriteData.get("documentId"));
                            favorite.setFolderName((String) favoriteData.get("folderName"));
                            favorite.setCreateTime(java.time.LocalDateTime.now());
                            favorite.setStatus(1);

                            // 检查是否已存在
                            if (!checkFavoriteExists(userId, favorite.getDocumentId())) {
                                save(favorite);
                                importedCount++;
                            }
                        } catch (Exception e) {
                            log.warn("导入单个收藏失败: {}", favoriteData, e);
                        }
                    }
                }
            }

            log.info("收藏导入完成: userId={}, importedCount={}", userId, importedCount);
            return importedCount;

        } catch (Exception e) {
            log.error("收藏导入失败: userId={}", userId, e);
            return 0;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer cleanupInvalidFavorites() {
        log.info("清理无效收藏");
        
        return baseMapper.cleanupInvalidFavorites();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean syncFavoriteStatistics(String documentId) {
        log.info("同步收藏统计: documentId={}", documentId);
        
        return baseMapper.syncFavoriteStatistics(documentId) > 0;
    }

    /**
     * 转换为VO
     */
    private DocumentFavoriteVO convertToVO(DocumentFavorite favorite) {
        DocumentFavoriteVO vo = new DocumentFavoriteVO();
        BeanUtils.copyProperties(favorite, vo);
        
        // 设置状态名称
        if (favorite.getFavoriteStatus() != null) {
            vo.setStatusName(favorite.getFavoriteStatus().getDescription());
        }
        
        // 设置状态信息
        vo.setIsActive(favorite.isActive());
        vo.setIsDefaultFolder(favorite.isDefaultFolder());
        vo.setFavoriteDays(favorite.getFavoriteDays());
        vo.setIsRecentFavorite(favorite.isRecentFavorite(7)); // 7天内为最近收藏
        
        return vo;
    }

    /**
     * 检查收藏是否已存在
     */
    private boolean checkFavoriteExists(String userId, String documentId) {
        return count(new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<DocumentFavorite>()
                .eq("user_id", userId)
                .eq("document_id", documentId)
                .eq("status", 1)) > 0;
    }
}
